import Vue from "vue";
import Store from "@/store/index";
import router from "../router/index";
import {
  Notification,
  MessageBox,
  Message,
  Loading
} from 'element-ui'

// 个人信息
import {
  getUserProfile
} from "@/api/system/user.js";
import {
  getMessageList,
  getName,
  getImList
} from "@/BMViews/api/upload/index.js";

import {
  getTrtcUserSigApi,
} from "@/BMViews/api/upload/index.js";

import {
  TUICallEngine,
  TUICallEvent
} from "tuicall-engine-webrtc"
import * as GenerateTestUserSig from "@/BMViews/debug/GenerateTestUserSig.js";

/**
 * tencentCall
 *
 * @param {Object} rules 验证字段的规则
 * @param {Object} messages 验证字段的提示信息
 * TSignaling文档
 * https://web.sdk.qcloud.com/component/tsignaling/doc/zh-cn/TSignaling.html#setLogLevel
 * tcrc文档
 * https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/TRTC.Logger.html#.LogLevel
 */
class TencentCall {

  constructor(wsUrl = "", wsId = 1) {
    Object.assign(this, {
      tuiCallEngine: '',
      data: {
        userId: '',
        types: 0,    //1：语音  2：视频  3：群语音  4：群视频
        // userType: 0, // 1：拨打电话者 2：被邀请者
        callShow: 0, //显示隐藏
        callState: 0, //通话状态，0：待机，1：通话中 2:拒绝 3:对方取消 4:无人应答 5：通话结束
        isDial: 0, //拨打状态
        isCall: 0, //是否来电，1：拨打，2：来电
        userList: [],
      },
    });
    this.__init();
  }



  /**
   * __init
   */
  __init() {
    this.__initMethods();
    this.__initDefaults();
    this.__initData();
  }

  /**
   * 初始化数据
   */
  __initData() {}

  /**
   * 初始化默认提示信息
   */
  __initDefaults() {
    this.defaults = {
      messages: {
        required: "这是必填字段。",
      },
    };
  }

  /**
   * 初始化
   */
  __initMethods() {
    // console.log("初始化Call");
    this.initialize();
  }

  //初始化
  initialize(url) {
    return new Promise(async (resolve, reject) => {
      this.data.userId = localStorage.getItem("userId");

      //获取sig
      // let restult = GenerateTestUserSig.genTestUserSig(this.data.userId);
      // let appids = Number(restult.sdkAppID);
      let restult = await getTrtcUserSigApi({userid: this.data.userId})
      console.log('获取sig',restult);
      let appids = Number(restult.data.appid);
      //初始化
      this.tuiCallEngine = TUICallEngine.createInstance({
        SDKAppID: appids, // 接入时需要将 0 替换为您的云通信应用的 SDKAppID
        tim: null, // tim 参数适用于业务中已存在 TIM 实例，为保证 TIM 实例唯一性
      })
      //设置日志等级
      console.log(this.tuiCallEngine);
      this.tuiCallEngine.setLogLevel(4)

      //登录
      this.goTrtcLogin(restult);
      //监听事件
      this.initListener()
      resolve(true)
    });
  }

  //获取音视频对象
  getCallObj(){
    return this.tuiCallEngine;
  }
  //监听事件
  initListener() {
    this.tuiCallEngine.on(TUICallEvent.INVITED, (res) => {
      // 收到视频通话的邀请
      console.log('收到视频通话的邀请', res);
      this.getUserInfo([res.sponsor]);
      Store.dispatch("setIsCall", 1);
      this.data.types = res.inviteData.callType
      this.data.isCall = 1;
      // console.log(this.data.isCall)
      // connectMeet()
    })

    this.tuiCallEngine.on(TUICallEvent.USER_ACCEPT, () => {
      // 对方接听
      console.log('对方接听了您发出的通话邀请');
      Store.dispatch("setCallState", 1);

      this.data.callState = 1;
      // showMeetRemote()
    })

    this.tuiCallEngine.on(TUICallEvent.REJECT, () => {
      // 对方拒绝
      console.log('对方拒绝了您发出的通话邀请')
      Store.dispatch("setCallState", 2);
      this.data.callState = 2;
      this.endCall();
    })

    this.tuiCallEngine.on(TUICallEvent.USER_ENTER, () => {
      // 有用户同意进入通话
      console.log('有用户同意进入通话');
      // showMeetRemote()
    })

    this.tuiCallEngine.on(TUICallEvent.CALLING_CANCEL, (res) => {
      // 对方以取消
      console.log('监听到结束',res)
      //来电并且不为自己挂断
      if (this.data.isCall == 1) {
        Store.dispatch("setCallState", 3);
        this.data.callState = 3;
        this.endCall();
      }

    })

    this.tuiCallEngine.on(TUICallEvent.CALLING_END, (res) => {
      // 对方以取消
      console.log('监听到通话结束',res)
      //通话结束
      this.data.callState = 5;
      Store.dispatch("setCallState", 5);
      this.endCall();
      if(res.userID == this.data.userId){
        //自己拨打的消息，发送记录
      }
    })

    this.tuiCallEngine.on(TUICallEvent.NO_RESP, () => {
      // 无人应答
      console.log('无人接听')
      Store.dispatch("setCallState", 4);
      this.data.callState = 4;
      this.endCall();
    })
  }

  //登录
  goTrtcLogin(data) {
    this.tuiCallEngine.login({
      userID: this.data.userId,
      // userSig: data.userSig,
      userSig: data.data.sign
    }).then(res => {
      // success
      console.log(this.data.userId, '音视频登录成功')
      // this.setUserInfo()
    }).catch(error => {
      console.warn('音视频登录 error:', error)
    })
  }



  //设置头像
  setUserInfo() {
    let userInfo = Store.state.user.userInfo;
    console.log(userInfo);
    this.tuiCallEngine.setSelfInfo({
      nickName: userInfo.nickName,
      avatar: userInfo.avatar,
    }).then(() => {
      //success
    }).catch(error => {
      console.warn('setSelfInfo error:', error);
    });

  }

  //拨打语音电话
  goCall(userId) {
    const loading = Loading.service();
    // Vue.$set(this.data,'isDial',1)
    this.tuiCallEngine.call({
      userID: userId, // 用户 ID
      type: 1 // 通话类型，0-未知， 1-语音通话，2-视频通话
    }).then(res => {
      console.log('拨号成功', res);
      //获取用户信息
      this.getUserInfo([userId]);
      this.data.types = 1;   //设置类型为语音
      this.data.isDial = 1
      Store.dispatch("setIsDial", 1);
      loading.close();
      // success
    }).catch(error => {
      loading.close();
      Message({
        type: 'error',
        message: '账号不存在或未登录'
      })

      console.log('账号不存在或未登录');
      this.endCall();
      console.log('拨打 error:', error)
    })
  }

  //拨打视频电话
  goVideoCall(userId) {
    const loading = Loading.service();
    this.tuiCallEngine.call({
      userID: userId, // 用户 ID
      type: 2 // 通话类型，0-未知， 1-语音通话，2-视频通话
    }).then(res => {
      console.log('视频拨号成功', res);
      this.getUserInfo([userId]);
      this.data.types = 2;   //设置类型为视频
      this.data.isDial = 1
      Store.dispatch("setIsDial", 1);
      loading.close();
    }).catch(error => {
      loading.close();
      Message({
        type: 'error',
        message: '账号不存在或未登录'
      })
      console.log('账号不存在或未登录');
      this.endCall();
      console.log('拨打 error:', error)
    })
  }

  //打开摄像头

  // 显示本地视频画面


  //接听电话
  connectMeet() {
    return new Promise((resolve, reject) => {
      this.tuiCallEngine.accept().then(res => {
        console.log('接听', res);
        resolve()
        // showMeetRemote()
      }).catch(error => {
        console.warn('接通 error:', error)
      })
    })
  }

  //拒绝
  rejectMeet() {
    return new Promise((resolve, rejects) => {
      this.tuiCallEngine.reject().then((res) => {
        console.log('拒接', res);
        this.endCall();

        resolve(true);
        //success
      }).catch(error => {
        console.warn('reject error:', error);
      });
    })

  }

  // 取消通话
  handleCancelCallUser() {
    return new Promise((resolve, reject) => {
      this.tuiCallEngine.hangup().then(() => {
        // success
        console.log('取消成功');
        this.endCall();
        resolve(true)
      }).catch(error => {
        console.warn('hangup error:', error)
      })
    })
  }

  //初始化状态
  endCall() {
    setTimeout(() => {
      this.data.isDial = 0;
      this.data.isCall = 0;
      this.data.callState = 0;
      Store.dispatch("setIsCall", 0);
      Store.dispatch("setIsDial", 0);
      Store.dispatch("setCallState", 0);
    }, 200)

  }

  //登出
  goTrtclogout(){
    let promise = this.tuiCallEngine.logout();
    promise.then((res) => {
        //success
        console.log('退出音视频登录 success:', res);
        this.destroyInstance();
        this.endCall()
    }).catch(error => {
        console.warn('退出音视频登录 error:', error);
    });
  }
  destroyInstance(){
    this.tuiCallEngine.destroyInstance().then(() => {
        //success
    }).catch(error => {
        console.warn('destroyInstance error:', error);
    });
  }


  //获取用户信息
  async getUserInfo(userIds) {
    let res = await getName({
      userIds: userIds?.join(',')
    })
    console.log('获取用户信息', res);
    this.data.userList = res.data;
  }



}

//循环 让对象的每一个属性都变成可观测的
function defineReactive(obj, key, val) {
  if (arguments.length === 2) {
    val = obj[key]
  }
  if (typeof val === 'object') {
    //递归
    new Observer(val)
  }
  Object.defineProperty(obj, key, {
    enumerable: true, //可枚举
    configurable: true,
    get() {
      console.log(`${key} 属性被读取了`);
      return val;
    },
    set(newVal) {
      console.log(`${key}属性被修改了,新的值为${newVal}`);
      val = newVal
    }
  })
}

export default TencentCall;
